﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using MavenThought.Commons.WPF.Events;
using Microsoft.Practices.ServiceLocation;
using TFS.Kanban.Commons;
using TFS.Kanban.Domain;
using TFS.Kanban.Domain.Events;
using TFS.Kanban.Domain.Services;
using TFS.Kanban.Modules.KanbanBoard.Interfaces;

namespace TFS.Kanban.Modules.KanbanBoard.ViewModels
{
    public class BoardViewModel : ViewModelBase<BoardViewModel>
    {
        private readonly IEventAggregator _eventAggregator;
        private readonly IUserStoryService _userStoryService;

        /// <summary>
        /// Initializes a new instance of the BoardViewModel class.
        /// </summary>
        public BoardViewModel(IEventAggregator eventAggregator, IUserStoryService userStoryService)
        {
            _eventAggregator = eventAggregator;
            _userStoryService = userStoryService;

            SubscribeToEvents();
        }

        #region Properties

        protected IProject Project { get; set; }

        private ICollection<ILaneViewModel> _lanes;
        public ICollection<ILaneViewModel> Lanes
        {
            get { return _lanes; }
            private set
            {
                if (_lanes != value)
                {
                    _lanes = value;
                    OnPropertyChanged(x => x.Lanes);
                }
            }
        }

        public Int32 NumberOfLanes { get { return Lanes != null ? Lanes.Count() : 0; } }

        #endregion

        #region CRUD

        private void LoadProject(IProject projectToLoad)
        {
            this.Project = projectToLoad;
        }

        private void LoadIteration(IProject project, IIteration iterationToLoad)
        {
            var userStories = _userStoryService.GetUserStories(iterationToLoad);

            var lanesToLoad = userStories.Select(x => x.State).Distinct();

            this.Lanes = new ObservableCollection<ILaneViewModel>();

            foreach (var laneToLoad in lanesToLoad)
            {
                var laneViewModel = ServiceLocator.Current.GetInstance<ILaneViewModel>();

                var state = laneToLoad;
                var cards = userStories.Where(x => x.State == state);

                laneViewModel.Load(laneToLoad, cards);

                this.Lanes.Add(laneViewModel);
            }
        }

        #endregion

        #region Event Handling

        private void SubscribeToEvents()
        {
            _eventAggregator.Subscribe<IProjectSelected>(ProjectLoaded);
            _eventAggregator.Subscribe<IIterationSelected>(IterationLoaded);
            _eventAggregator.Subscribe<IPathSelected>(PathSelected);
        }

        private void PathSelected(IPathSelected arg)
        {
            LoadIteration(this.Project, new Iteration{ Path = arg.Path});
        }

        private void IterationLoaded(IIterationSelected args)
        {
            LoadIteration(this.Project, args.Iteration);
        }

        private void ProjectLoaded(IProjectSelected args)
        {
            LoadProject(args.Project);
        }

        #endregion
    }
}
